﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;
using Qplus.protocol;
using Qplus.beans;
using Qplus.UI;

namespace Qplus.Infrastructure
{
    public class ConnectListener : TCPConnectionListener
    {
        /**
	     * 消息头
	     */
	    protected byte[] head = new byte[5];
	    /**
	     * 消息体
	     */
	    protected byte[] content = new byte[TCPConnection.BUFFER_SIZE];
	
	    /**
	     * head是否读满，如果是false则表示head还未读满
	     */
	    protected Boolean headFull = false;
	
	    /**
	     * dirty数据，是此次读取数据后剩余的不能构成一个完整的tcp包得数据
	     */
	    protected byte[] dirty = new byte[TCPConnection.BUFFER_SIZE];
	    /**
	     * dirty数据的长度
	     */
	    protected int dirtyLen = 0;
	
	    
	    public virtual int onReceivedData(TCPConnection tcp_conn, byte[] data, int len) {
		    //添加流量
    //		Nettraffic.getInstance().addNettraffic(len);
            //		 Debug.WriteLine("接收数据" + (len + dirtyLen));
		    int offset = 0;
		    //先把上次遗留的数据合并
            //Array.Copy(dirty, 0, data, 0, dirtyLen);
		    //len += dirtyLen;
		    Boolean error = false;
		    //初始化偏移
		    while(true){
			    //如果剩余数据够一个head则读消息头
			    if (headFull == false && len - offset >= head.Length) {
				    //拷贝头数据到head，偏移加4
                    Array.Copy(data, offset, head, 0, head.Length);
				    offset += head.Length;
                    //				 Debug.WriteLine("head offset is " + offset);
    //				int id = ProtocolUtil.getMessageID(head);
    //				int pacakgeLen = ProtocolUtil.getContentLength(head);
                    //				 Debug.WriteLine("读消息头" + id + " " + pacakgeLen);
				    //head读满了，下面开始读content
				    headFull = true;
			    }else if(headFull == false && len - offset < head.Length){
				    //如果数据不够一个包的内容
				    dirtyLen = len - offset;
                    //				 Debug.WriteLine("读消息头，长度不够还差" + (4 - dirtyLen) + " 剩下" + dirtyLen);
				    try{
                        Array.Copy(data, offset, dirty, 0, dirtyLen);
				    }catch (Exception e) {
					    error = true;
					    break;
				    }
				    //退出,等待下一次数据
				    break;
			    }
			    if(headFull){
				    //如果头已经读了，则开始读content
				    //解析消息id和数据长度
				    int id = ProtocolUtil.getMessageID(head);
				    int pacakgeLen = ProtocolUtil.getContentLength(head);
    //				Log.d(TAG, "读内容" + id + " " + pacakgeLen);
				    if(len - offset >= pacakgeLen){
                        // Debug.WriteLine( "读内容1" + id + " " + pacakgeLen);
					    //如果数据长度大于这个包的长度说明这个包是完整的，则把包读完
					    headFull = false;
					    //拷贝数据到content
					    try{
                            Array.Copy(data, offset, content, 0, pacakgeLen);
					    }catch (Exception e) {
						    error = true;
						    break;
					    }
					    offset += pacakgeLen;
					
					    //分发数据
					    Debug.WriteLine("read package head, message id = " + id + " len = " + pacakgeLen);
					    try{
    //						// 通过id获取相对应的管道的输出流
						    InPacket packet = PipManager.getInstance().getPacket(id);
                            
						    packet.setData(new byte[pacakgeLen]);
                            Array.Copy(content, 0, packet.getData(), 0, pacakgeLen);
						    onReceivePacket(packet);
					    }catch (Exception e) {
						    Debug.WriteLine("消息id不存在, 接收到的 id = " + id);
						    InPacket packet = new ERROR_PACKET(ERROR_PACKET.ERROR_UNKNOWN_PACKET);
						    onReceivePacket(packet);
    //						error = true;
    //						break;
					    }
				    }else if(len - offset < pacakgeLen){
    //					Log.d(TAG, "读内容长度不够" + id);
					    //如果数据不够一个包的内容
					    dirtyLen = len - offset;
                        //					 Debug.WriteLine("读内容，长度不够,还差" + (pacakgeLen - dirtyLen) + " 剩下" + dirtyLen);
					    try{
                            Array.Copy(data, offset, dirty, 0, dirtyLen);
					    }catch (Exception e) {
						    error = true;
						    break;
					    }
					    //退出
					    break;
				    }
			    } 
		    }
		    if(error){
			    return -1;
		    }else {
			    return dirtyLen;
		    }
	    }


        public virtual void onConnectionTerminated(TCPConnection tcp_conn, Exception error)
        {
		    
		    if(error != null){
			    InPacket packet = new ERROR_PACKET(ERROR_PACKET.ERROR_CONNECT_EXCEPTION);
			    onReceivePacket(packet);
		    }else {
			    QUser user = QplusT.getInstance().getUser();
                if (user.getIsOnline())
                {
				    InPacket packet = new ERROR_PACKET(ERROR_PACKET.ERROR_CONNECT_EXCEPTION);
				    onReceivePacket(packet);
			    }
		    }
	    }


        public virtual void onConnected(TCPConnection tcp_conn)
        {
		    Debug.WriteLine("socket is connected");
	    }

	    public void onReceivePacket(InPacket packet){}

    }

}
